package com.woniu.cinema.controller;

import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniu.cinema.request.DynamicMovieRequest;
import com.woniu.cinema.vo.MovieVo;
import com.woniu.common.constant.Constants;
import com.woniu.common.core.page.TableSupport;
import com.woniu.common.core.redis.RedisCache;
import com.woniu.common.enums.ExceptionCode;
import com.woniu.common.exception.CustomException;
import com.woniu.common.utils.ServletUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.woniu.common.annotation.Log;
import com.woniu.common.core.controller.BaseController;
import com.woniu.common.core.domain.AjaxResult;
import com.woniu.common.enums.BusinessType;
import com.woniu.cinema.domain.Movie;
import com.woniu.cinema.service.MovieService;
import com.woniu.common.utils.poi.ExcelUtil;
import com.woniu.common.core.page.TableDataInfo;

/**
 * 影片信息Controller
 * 
 * @author yy
 * @date 2021-04-16
 */
@RestController
@RequestMapping("/cinema/movie")
public class MovieController extends BaseController
{
    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private MovieService movieService;

    @Autowired
    private RedisCache redisCache;

    /**
     * 查询影片信息列表
     */
    @GetMapping("/list")
    public TableDataInfo list(Movie movie)
    {

        Integer cacheType = ServletUtils.getParameterToInt("cacheType")==null?-10000:ServletUtils.getParameterToInt("cacheType");
        String cacheMovieData = null;
        ObjectMapper mapper = new ObjectMapper();
        //根据查询类型，去redis中查询
        if(1==cacheType){
            cacheMovieData = (String)redisCache.getCacheObject(Constants.INDEX_CACHE_MOVIE_ONLINE);
        }else if(0==cacheType){
            cacheMovieData = (String)redisCache.getCacheObject(Constants.INDEX_CACHE_MOVIE_COMINGON);
        }else if(2==cacheType){
            cacheMovieData = (String)redisCache.getCacheObject(Constants.INDEX_CACHE_MOVIE_TOP_BOXOFFICE);
        }
        if(cacheMovieData!=null){
            try {
                List<Movie> movieList = mapper.readValue(cacheMovieData, new TypeReference<List<Movie>>() {});
                return getDataTable(movieList);
            } catch (JsonProcessingException e) {
                throw new CustomException(ExceptionCode.JSON_CONVERTION);
            }
        }

        RLock lock = redissonClient.getLock("redis:cache:movieinfo:lock");
        try{
            lock.lock();
            if(cacheMovieData!=null){
                List<Movie> movieList = null;
                try {
                    movieList = mapper.readValue(cacheMovieData, new TypeReference<List<Movie>>() {});
                    return getDataTable(movieList);
                } catch (JsonProcessingException e) {
                    throw new CustomException(ExceptionCode.JSON_CONVERTION);
                }
            }
            //缓存没有，去数据库查询
            startPage();
            List<Movie> list = movieService.selectMovieList(movie);
            TableDataInfo dataTable = getDataTable(list);

            //从数据库查询后，放入缓存中
            try {
                String movieListJsonArray = mapper.writeValueAsString(list);
                Random random = new Random();
                //缓存过期时间设置成随机数，防止同时过期，造成雪崩
                int rand = random.nextInt(10)+720;
                if(1==cacheType){
                    redisCache.setCacheObject(Constants.INDEX_CACHE_MOVIE_ONLINE,movieListJsonArray,rand, TimeUnit.HOURS);
                }else if(0==cacheType){
                    redisCache.setCacheObject(Constants.INDEX_CACHE_MOVIE_COMINGON,movieListJsonArray,rand, TimeUnit.HOURS);
                }else if(2==cacheType){
                    redisCache.setCacheObject(Constants.INDEX_CACHE_MOVIE_TOP_BOXOFFICE,movieListJsonArray,rand, TimeUnit.HOURS);
                }
            } catch (JsonProcessingException e) {
                throw new CustomException(ExceptionCode.JSON_CONVERTION);
            }

            return dataTable;
        }finally{
            lock.unlock();
        }


    }

    @RequestMapping("listAll")
    public List<MovieVo> listAllMovie(@RequestParam("id") Long id){
        List<MovieVo> list = movieService.listAll(id);
        return list;
    }

    @GetMapping("/list/dynamic")
    public TableDataInfo selectMovieListByDynamicFields(DynamicMovieRequest request){


        //缓存没有，去数据库查询
        startPage();
        List<Movie> list = movieService.selectMovieListByDynamicFields(request);
        TableDataInfo dataTable = getDataTable(list);


        return dataTable;
    }

    @GetMapping("listComingMovieListByCinema")
    public AjaxResult listComingMovieListByCinema(Long cinemaId){

        List<Movie> list = movieService.listComingMovieListByCinema(cinemaId);

        return AjaxResult.success(list);
    }


    /**
     * 导出影片信息列表
     */
    @Log(title = "影片信息", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(Movie movie)
    {
        List<Movie> list = movieService.selectMovieList(movie);
        ExcelUtil<Movie> util = new ExcelUtil<Movie>(Movie.class);
        return util.exportExcel(list, "movie");
    }

    /**
     * 获取影片信息详细信息
     */
    @GetMapping(value = "/{movieId}")
    public AjaxResult getInfo(@PathVariable("movieId") Long movieId)
    {
        return AjaxResult.success(movieService.selectMovieById(movieId));
    }

    /**
     * 获取影片信息详细信息
     */
    @GetMapping(value = "/queryMovieVo/{movieId}")
    public AjaxResult queryMovieVoById(@PathVariable("movieId") Long movieId)
    {
        return AjaxResult.success(movieService.selectMovieVoById(movieId));
    }


    /**
     * 新增影片信息
     */
    @Log(title = "影片信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Movie movie)
    {
        return toAjax(movieService.insertMovie(movie));
    }

    /**
     * 修改影片信息
     */
    @Log(title = "影片信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Movie movie)
    {
        return toAjax(movieService.updateMovie(movie));
    }

    /**
     * 删除影片信息
     */
    @Log(title = "影片信息", businessType = BusinessType.DELETE)
	@DeleteMapping("/{movieIds}")
    public AjaxResult remove(@PathVariable Long[] movieIds)
    {
        return toAjax(movieService.deleteMovieByIds(movieIds));
    }

    public static void main(String[] args) {
        Long a=null;
        Long b=null;
        Random random = new Random();
        int rand = random.nextInt(10);
        System.out.println(rand);
    }
}
